#[macro_use]
extern crate bitflags;

use std::fmt;

bitflags!{
     struct Flags : u32 {
        const A = 0b00000001;
        const B = 0b00000010;
        const C = 0b00000100;
        const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
    }
}

mod example{
    bitflags!{
        pub struct Flags1:u32{
            const A=0b00000001;
        }
    }
    bitflags!{
        struct Flags2:u32{
            const B: 0b00000010;
        }
    }
}

impl Flags {
    pub fn clear(&mut self){
        self.bits=0;
    }
}

impl fmt::Display for Flags{
    fn fmt(&self,f: &mut fmt::Formatter) -> fmt::Result{
        write!(f,"hi!")
    }
}

fn main() {
    let mut flags = Flags::A | Flags::B;
    flags.clear();

    assert!(flags.is_empty());
    assert_eq!(format!("{}",flags),"hi!");
    assert_eq!(format!("{:?}",Flags::A | Flags::B),"A | B");
    assert_eq!(format!("{:?}",Flags::B),"B");

    let e1 = Flags::A | Flags::C;
    let e2 = Flags::B | Flags::C;
    assert_eq!((e1 | e2), Flags::ABC);   // union
    assert_eq!((e1 & e2), Flags::C);     // intersection
    assert_eq!((e1 - e2), Flags::A);     // set difference
    assert_eq!(!e2, Flags::A);           // set complement

    let flag1 = example::Flags1::A;
    let flag2 = example::Flags2::B;
}
